home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / utils / inttools / hook.asm < prev    next >
Assembly Source File  |  1995-04-20  |  9KB  |  299 lines

  1. ;
  2. ;  Program to attatch a given interrupt vector to a specific address
  3. ;  Version One,  Steve Kemp  '95
  4. ;
  5. ;   Operation, either
  6. ;
  7. ;     HOOK [/?]
  8. ;   or
  9. ;     HOOK intnumber segment:offset   *** ALL NUMBERS IN HEX
  10. ;
  11. ;   Basically this routine was cobbled together in an hour from the Intview
  12. ; program, as such it is not the best way to do things, and is subject to
  13. ; strange input requirements... eg HOOK 21 0000:0000 not 0:0, and
  14. ; and HOOK 0F 1234:1234 not HOOK F 1234:1234
  15.  
  16. parser:
  17.         mov SI,80h
  18. parse_loop:
  19.         inc SI                    ; Get ready for next character
  20.         mov Dl,[SI]                ; Get character from command tail
  21.         cmp Dl,'/'                ; Switch??
  22.         jz found_slash            ; If so goto switch routine
  23.         cmp Dl,0Dh                ; End of tail??
  24.         jnz parse_loop            ; If not repeat
  25.  
  26.         cmp SI,81h                ; Still at start of tail??
  27.         jnz parameters_entered    ; If not continue
  28.         
  29.         mov DX,info_message        ; Else queue up error message
  30.         call print_string        ; Print it
  31.         jmp return2DOS            ; and return to DOS
  32.  
  33. parameters_entered:
  34.         call calculate_numbers    ; Calculate numbers on command line
  35.         call print_confirm        ; Print out the question info.
  36.  
  37.         mov Ah,08h                ; get a keypress
  38.         int 21h                    ; Here
  39.         or Al,32                ; Convert it to lowercase
  40.         cmp Al,'y'                ; Was it a 'Yes'
  41.         jz hook_interrupt        ; If so go ahead
  42.         mov DX,fail_mess        ; Get ready to print 'Aborted' message
  43.         call print_string        ; Do it,
  44.         jmp return2DOS            ; then eturn to DOS
  45.  
  46. hook_interrupt:
  47.         mov AX,0004                ; Multiply the int. number by four
  48.         mov BX,[int_number]
  49.         mul BX                    ; Now!
  50.         mov SI,AX                ; Point index to correct location in
  51.         mov CX,[segment_buffer]    ; table, get values to insert
  52.         mov BX,[offset_buffer]
  53.  
  54.         cli                        ; Stop all ints.
  55.         push DS                    ; Save the data segment
  56.         sub AX,Ax                ; AX=0000
  57.         push AX
  58.         pop DS                    ; DS=0000
  59.  
  60.         mov [DS:SI],BX            ; Update the offset entry
  61.         inc SI
  62.         inc SI
  63.         mov [DS:SI],CX            ; And the segment
  64.         
  65.         pop DS                    ; Restore the segment
  66.         sti                        ; Enable the maskable ints again.
  67.         mov DX,finished_mess    ; Tell user we did it
  68.         call print_string
  69.         jmp return2DOS
  70.  
  71.  
  72. found_slash:
  73.         inc SI                    ; Point to next letter
  74.         mov Dl,[SI]                ; Get it into Dl
  75.         cmp Dl,'?'                ; ? ?? If so print info about program
  76.         jz info    
  77.         push DX                    ; Otherwise invalid switch.  Save it
  78.         mov DX,invalid_switch    ; Print invalid switch message
  79.         call print_string        ; Here
  80.         pop DX                    ; Get back saved letter
  81.         add Dl,'A'-'a'            ; Print uppercase version of letter
  82.         mov Ah,02                ; Print a single character
  83.         int 21h                    ; Now!
  84. return2DOS:
  85.         mov Ah,4ch                ; Return to DOS
  86.         int 21h                    ; There!
  87.  
  88. info:
  89.         mov DX,info_message        ; Point to info. string
  90.         call print_string        ; Print the string
  91.         jmp return2DOS            ; finished!
  92.  
  93. ;
  94. ;   This routine calculates the parameters from the command line.
  95. ; They MUST be in the correct format. Code could be improved here a lot
  96. ; ... version two ...
  97. calculate_numbers:
  98.         mov SI,82h                    ; Number is first parameter on Command
  99.         mov DI,ascii_buffer            ; Put a copy of it into the temporary
  100.         movsw                        ; buffer
  101.         movsw
  102.  
  103.         push SI                        ; Save position
  104.                                     ; [Calculating the int number here]
  105.         mov SI,ascii_buffer            ; Point to int_number
  106.         call hex_number                ; Convert it to a number
  107.         mov DX,[temp]                ; Get it from the store
  108.         mov [int_number],DX            ; where it was placed, and put it in the
  109.                                     ; interrupt number store
  110.                                     ; [Calculating Segment now]
  111.         pop SI                        ; Get back the pointer to the 
  112.         dec SI                        ; command line, point to the next byte
  113.         push SI                        ; Save the pointer
  114.         call hex_number                ; Work out the high byte.
  115.         mov dx,[temp]                ; Get the result
  116.         mov Dh,Dl                    ; Put the high byte in the right place
  117.         mov [segment_buffer],dx        ; Store it in the store
  118.         pop SI                        ; Get back the pointer    
  119.         inc SI                        ; Point to the low-byte digits
  120.         inc SI
  121.         push SI                        ; Save pointer on the stack
  122.         call hex_number                ; Work out the low-byte
  123.         mov dx,[temp]                ; Get it from the store
  124.         mov ax,[segment_buffer]        ; Get the previously calculated hb
  125.         mov dh,ah                    ; Form the word
  126.         mov [segment_buffer],dx        ; Finished, put the word in the store
  127.  
  128.                                     ; [Calculating the offset now]
  129.         pop SI                        ; Get our pointer back
  130.         inc SI                        ; Point past the low segment byte
  131.         inc SI
  132.         inc SI                        ; And the deliminator
  133.         push SI                        ; Save pointer  for later
  134.         call hex_number                ; Work out high byte
  135.         mov dx,[temp]                ; get the result
  136.         mov Dh,Dl                    ; Put high byte in the right place
  137.         mov [offset_buffer],dx        ; which is the offset_buffer
  138.         pop SI                        ; Get back the pointer
  139.         inc SI                        ; increase to point to the low byte's
  140.         inc SI                        ; digits
  141.         call hex_number                ; Calculate them.
  142.         mov dx,[temp]                ; Add up the high, and low bytes
  143.         mov ax,[offset_buffer]
  144.         mov dh,ah
  145.         mov [offset_buffer],dx        ; Stick result in the store..
  146.  
  147.         ret                            ; Finished calculating parameters
  148.  
  149. ;
  150. ;  Routine to turn a ascii value into a number.  Result put in [Temp]
  151. ;
  152. hex_number:
  153.         mov Dl,[SI]                ; Get a character
  154.         inc SI                    ; Move pointer up by one
  155.         mov Dh,[SI]                ; Get another character
  156.         or Dh,32                ; Convert secont character to lower case
  157.         cmp Dh,'h'                ; Is it a 'h'
  158.         jz one_digit_hex        ; If so number is one ASCII-byte long
  159.         
  160. two_digit_hex:                    ; Else it MUST be two ASCII-bytes long
  161.         cmp Dl,'9'
  162.         jle less_than_nine_1    ; Is it a number??
  163.         or Dl,32                ; If not its a letter, lowercase it becomes
  164.         sub dl,'a'-10-'0'        ; Adjust value
  165. less_than_nine_1:
  166.         sub Dl,'0'                ; Convert it to number 0-15
  167.         mov AX,16                ; Get ready to multiply by 16
  168.         mov Dh,00                
  169.         mul DX                    ; Do it! (Result in AX)
  170.         push AX                    ; Save result on stack
  171.         mov Dl,[SI]                ; Get next digit
  172.         call one_digit_hex        ; Treat it as a one digit number
  173.         pop AX                    ; Restore the value that we saved
  174.         add AX,DX                ; Add high+low results
  175.         mov [temp],AX            ; Finally store the result in the bufffer
  176.         ret                        ; Finished (Phew!)
  177.  
  178. one_digit_hex:
  179.         cmp Dl,'9'                ; Is it a digit??
  180.         jle less_than_nine_2    ; If so goto digit routine
  181.         or dl,32                ; Convert letter to lower case
  182.         sub Dl,'a'-'9'-1        ; Adjust it
  183. less_than_nine_2:
  184.         sub Dl,'0'                ; Convert it to a number 0-15
  185.         mov Dh,00                ; Blank out high byte
  186.         mov [temp],DX            ; Store in the buffer
  187.         ret                        ; Return
  188.  
  189. ;
  190. ; This routine prints the contents of Ah as a two-byte hex number.
  191. ;
  192. print_hex:
  193.          mov al,ah
  194.          shr ah,1
  195.          shr ah,1
  196.          shr ah,1
  197.          shr ah,1
  198.          cmp ah,9
  199.          jbe next1
  200.          add ah,7
  201. next1:
  202.         add ah,'0'
  203.          and al,0fh
  204.         cmp al,9
  205.          jbe next2
  206.          add al,7
  207. next2:
  208.         add al,'0'
  209.         push cx
  210.         mov cl,ah
  211.         mov ch,al
  212.         mov Ah,02
  213.         mov Dl,cl
  214.         int 21h
  215.         mov Ah,02
  216.         mov Dl,ch
  217.         int 21h
  218.         pop cx
  219.         ret
  220.  
  221. print_confirm:
  222.         mov DX,first_message    ; Print first part of message
  223.         call print_string        ; now!
  224.         
  225.         mov ax,[int_number]        ; print int number
  226.         mov ah,al
  227.         call print_hex            ; Here
  228.  
  229.         mov DX,second_message    ; print more message
  230.         call print_string        ; here
  231.  
  232. print_segment:                    ; Print the segment
  233.         mov DX,[segment_buffer]    ; Get a copy of the segment address
  234.         push DX                    ; Save it onto the stack
  235.         mov Ah,Dh                ; Get ready to print the high byte
  236.         call print_hex            ; Do it!
  237.         pop DX                    ; Retore the value
  238.         mov Ah,Dl                ; Print the low byte
  239.         call print_hex            ; Here
  240.  
  241.         mov ah,2                ; Print a single character
  242.         mov Dl,':'                ; A seperator
  243.         int 21h                    ; Now!
  244.  
  245. print_offset:
  246.         mov DX,[offset_buffer]    ; Get a copy of the segment offset
  247.         push DX                    ; Save it onto the stack
  248.         mov Ah,Dh                ; Get ready to print the high byte
  249.         call print_hex            ; Do it!
  250.         pop DX                    ; Retore the value
  251.         mov Ah,Dl                ; Print the low byte
  252.         call print_hex            ; Here
  253.  
  254.         mov Ah,02                ; Print a single character
  255.         mov Dl,'?'                ; A question mark
  256.         int 21h                    ; Now!
  257.  
  258.         ret                        ; Return
  259.  
  260. print_string:
  261.         mov Ah,09h                    ; Get ready to output the string addressed
  262.         int 21h                        ; By DX. Do it.
  263.         ret                            ; Return
  264.  
  265. ; **************************************************************************
  266. ; * Output Strings and Data area *
  267. ; ********************************
  268.  
  269. invalid_switch:
  270.         db "Invalid switch - /","$"
  271. info_message:
  272.         db "HOOK Version One - Steven Kemp 1995",0ah,0dh
  273.         db "   Usage",0ah,0dh
  274.         db "    HOOK [/?]         - Gives this info.",0ah,0dh
  275.         db "   Or",0ah,0dh
  276.         db "    HOOK xx ssss:oooo - Hooks int. number xx (hex), to",,0ah,0dh
  277.         db "                        segment ssss, offset oooo.",0ah,0dh
  278.         db 0ah,0dh
  279.         db "    ALL NUMBERS MUST BE IN FULL HEX, e.g. HOOK 0F 1234:0001"
  280.         db "$"
  281. first_message:
  282.         db " REALLY hook the int ","$"
  283. second_message:
  284.         db "h handler to ","$"
  285. fail_mess:
  286.         db 0ah,0dh,"Hook operation cancelled at users request.","$"
  287. finished_mess:
  288.         db 0ah,0dh,"Interrupt hooked.","$"        
  289. ascii_buffer:
  290.         db 00,00,00
  291. temp:
  292.         dw 0000
  293. int_number:
  294.         dw 0000h
  295. offset_buffer:
  296.         dw 0000h
  297. segment_buffer:
  298.         dw 0000h
  299.